#include <fstream>
#include "json2mtl.h"

// view: https://blog.csdn.net/m0_37591671/article/details/74610510
int json2mtl(JsonFile jsonFile, const char *targetPath)
{
    std::ofstream out(targetPath);
    out.setf(std::ios_base::fixed, std::ios_base::floatfield);
    out.precision(2);

    out << "#Bin2Obj MTL File: \n"
        << "#Material Count: " << jsonFile.Materials.size() << "\n";

    for (JsonMaterial material : jsonFile.Materials)
    {
        out << "newmtl " << material.DbgName << "\n"     // 定义一个新材质
            << "illum " << material.Illumination << "\n" // 指定材质的光照模型
            << "Kd " << material.ColorDiffuse[0] << " "
            << material.ColorDiffuse[1] << " "
            << material.ColorDiffuse[2]
            << "\n" // 漫反射 Kd r g b
            << "Ka " << material.ColorAmbient[0] << " "
            << material.ColorAmbient[1] << " "
            << material.ColorAmbient[2]
            << "\n"                  // 环境反射：Ka r g b ——用RGB颜色值来表示，g和b两参数是可选的。如果只指定了r的值，则g和b的值都等于r的值。三个参数一般取值范围为0.0~1.0，在此范围外的值则相应的增加或减少反射率;
            << "Tf 1.00 1.00 1.00\n" // Tf r g b 滤光透射率
            << "Ni 1.00\n"           // 指定材质表面的光密度，即折射值。 ptical density是光密度值，可在0.001到10之间进行取值。若取值为1.0，光在通过物体的时候不发生弯曲。玻璃的折射率为1.5。取值小于1.0的时候可能会产生奇怪的结果，不推荐。
            << "Ks " << material.ColorSpecular[0] << " "
            << material.ColorSpecular[1] << " "
            << material.ColorSpecular[2]
            << "\n"        // 镜面反射：Ks r g b
            << "Ns 0.00\n" // 反射指数 Ns exponent 指定材质的反射指数，定义了反射高光度。 exponent是反射指数值，该值越高则高光越密集，一般取值范围在0~1000
            << "d 1.00\n"; // d factor表示物体融入背景的数量，取值范围为0.0~1.0，取值为1.0表示完全不透明，取值为0.0时表示完全透明

        if (material.AlphaTest > 0.1)
        {
            out << "alpha " << material.AlphaTest << "\n";
        }

        if (!material.MapDiffuse.empty())
        {
            out << "map_Kd " << material.MapDiffuse // filename 为漫反射指定颜色纹理文件(.mpc)或程序纹理文件(.cxc)，或是一个位图文件。
                << std::endl;
        }

        if (!material.MapAlpha.empty())
        {
            out << "map_d " << material.MapAlpha << std::endl;
        }
    }

    return 0;
}